﻿using System;
using System.Diagnostics;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using HslCommunication.Core;
using HslCommunication.Core.Net;
using HslCommunication.LogNet;
using HslCommunication.Reflection;

namespace HslCommunication.Profinet.Geniitek
{
	/// <summary>
	/// Geniitek-VB31 型号的智能无线振动传感器，来自苏州捷杰传感器技术有限公司
	/// </summary>
	// Token: 0x020000A1 RID: 161
	public class VibrationSensorClient : NetworkXBase
	{
		/// <summary>
		/// 使用指定的ip，端口来实例化一个默认的对象
		/// </summary>
		/// <param name="ipAddress">Ip地址信息</param>
		/// <param name="port">端口号信息</param>
		// Token: 0x06000BFF RID: 3071 RVA: 0x000472F0 File Offset: 0x000454F0
		public VibrationSensorClient(string ipAddress = "192.168.1.1", int port = 3001)
		{
			this.ipAddress = HslHelper.GetIpAddressFromInput(ipAddress);
			this.port = port;
			this.byteTransform = new ReverseBytesTransform();
		}

		/// <summary>
		/// 连接服务器，实例化客户端之后，至少要调用成功一次，如果返回失败，那些请过一段时间后重新调用本方法连接。<br />
		/// After connecting to the server, the client must be called at least once after instantiating the client.
		/// If the return fails, please call this method to connect again after a period of time.
		/// </summary>
		/// <returns>连接是否成功</returns>
		// Token: 0x06000C00 RID: 3072 RVA: 0x00047374 File Offset: 0x00045574
		public OperateResult ConnectServer()
		{
			Socket coreSocket = this.CoreSocket;
			if (coreSocket != null)
			{
				coreSocket.Close();
			}
			OperateResult<Socket> operateResult = base.CreateSocketAndConnect(this.ipAddress, this.port, this.connectTimeOut);
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				this.CoreSocket = operateResult.Content;
				try
				{
					this.CoreSocket.BeginReceive(new byte[0], 0, 0, SocketFlags.None, new AsyncCallback(this.ReceiveAsyncCallback), this.CoreSocket);
				}
				catch (Exception ex)
				{
					return new OperateResult(ex.Message);
				}
				this.closed = false;
				VibrationSensorClient.OnClientConnectedDelegate onClientConnected = this.OnClientConnected;
				if (onClientConnected != null)
				{
					onClientConnected();
				}
				Timer timer = this.timerCheck;
				if (timer != null)
				{
					timer.Dispose();
				}
				this.timerCheck = new Timer(new TimerCallback(this.TimerCheckServer), null, 2000, 5000);
				result = OperateResult.CreateSuccessResult();
			}
			return result;
		}

		/// <summary>
		/// 关闭Mqtt服务器的连接。<br />
		/// Close the connection to the Mqtt server.
		/// </summary>
		// Token: 0x06000C01 RID: 3073 RVA: 0x00047470 File Offset: 0x00045670
		public void ConnectClose()
		{
			bool flag = !this.closed;
			if (flag)
			{
				this.closed = true;
				Thread.Sleep(20);
				Socket coreSocket = this.CoreSocket;
				if (coreSocket != null)
				{
					coreSocket.Close();
				}
				Timer timer = this.timerCheck;
				if (timer != null)
				{
					timer.Dispose();
				}
			}
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Geniitek.VibrationSensorClient.ConnectServer" />
		// Token: 0x06000C02 RID: 3074 RVA: 0x000474C0 File Offset: 0x000456C0
		[DebuggerStepThrough]
		public Task<OperateResult> ConnectServerAsync()
		{
			VibrationSensorClient.<ConnectServerAsync>d__3 <ConnectServerAsync>d__ = new VibrationSensorClient.<ConnectServerAsync>d__3();
			<ConnectServerAsync>d__.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
			<ConnectServerAsync>d__.<>4__this = this;
			<ConnectServerAsync>d__.<>1__state = -1;
			<ConnectServerAsync>d__.<>t__builder.Start<VibrationSensorClient.<ConnectServerAsync>d__3>(ref <ConnectServerAsync>d__);
			return <ConnectServerAsync>d__.<>t__builder.Task;
		}

		// Token: 0x06000C03 RID: 3075 RVA: 0x00047504 File Offset: 0x00045704
		private void OnVibrationSensorClientNetworkError()
		{
			bool flag = this.closed;
			if (!flag)
			{
				bool flag2 = Interlocked.CompareExchange(ref this.isReConnectServer, 1, 0) == 0;
				if (flag2)
				{
					try
					{
						bool flag3 = this.OnNetworkError == null;
						if (flag3)
						{
							ILogNet logNet = base.LogNet;
							if (logNet != null)
							{
								logNet.WriteInfo("The network is abnormal, and the system is ready to automatically reconnect after 10 seconds.");
							}
							for (;;)
							{
								for (int i = 0; i < 10; i++)
								{
									Thread.Sleep(1000);
									ILogNet logNet2 = base.LogNet;
									if (logNet2 != null)
									{
										logNet2.WriteInfo(string.Format("Wait for {0} second to connect to the server ...", 10 - i));
									}
								}
								OperateResult operateResult = this.ConnectServer();
								bool isSuccess = operateResult.IsSuccess;
								if (isSuccess)
								{
									break;
								}
								ILogNet logNet3 = base.LogNet;
								if (logNet3 != null)
								{
									logNet3.WriteInfo("The connection failed. Prepare to reconnect after 10 seconds.");
								}
							}
							ILogNet logNet4 = base.LogNet;
							if (logNet4 != null)
							{
								logNet4.WriteInfo("Successfully connected to the server!");
							}
						}
						else
						{
							EventHandler onNetworkError = this.OnNetworkError;
							if (onNetworkError != null)
							{
								onNetworkError(this, new EventArgs());
							}
						}
						this.activeTime = DateTime.Now;
						Interlocked.Exchange(ref this.isReConnectServer, 0);
					}
					catch
					{
						Interlocked.Exchange(ref this.isReConnectServer, 0);
						throw;
					}
				}
			}
		}

		// Token: 0x06000C04 RID: 3076 RVA: 0x0004765C File Offset: 0x0004585C
		[DebuggerStepThrough]
		private void ReceiveAsyncCallback(IAsyncResult ar)
		{
			VibrationSensorClient.<ReceiveAsyncCallback>d__5 <ReceiveAsyncCallback>d__ = new VibrationSensorClient.<ReceiveAsyncCallback>d__5();
			<ReceiveAsyncCallback>d__.<>t__builder = AsyncVoidMethodBuilder.Create();
			<ReceiveAsyncCallback>d__.<>4__this = this;
			<ReceiveAsyncCallback>d__.ar = ar;
			<ReceiveAsyncCallback>d__.<>1__state = -1;
			<ReceiveAsyncCallback>d__.<>t__builder.Start<VibrationSensorClient.<ReceiveAsyncCallback>d__5>(ref <ReceiveAsyncCallback>d__);
		}

		// Token: 0x06000C05 RID: 3077 RVA: 0x0004769C File Offset: 0x0004589C
		private void TimerCheckServer(object obj)
		{
			bool flag = this.CoreSocket != null;
			if (flag)
			{
				bool flag2 = !this.closed;
				if (flag2)
				{
					bool flag3 = (DateTime.Now - this.activeTime).TotalSeconds > (double)this.checkSeconds;
					if (flag3)
					{
						bool flag4 = this.CheckTimeoutCount == 0;
						if (flag4)
						{
							ILogNet logNet = base.LogNet;
							if (logNet != null)
							{
								logNet.WriteDebug(StringResources.Language.NetHeartCheckTimeout);
							}
						}
						this.CheckTimeoutCount = 1;
						this.OnVibrationSensorClientNetworkError();
					}
					else
					{
						this.CheckTimeoutCount = 0;
					}
				}
			}
		}

		// Token: 0x06000C06 RID: 3078 RVA: 0x00047734 File Offset: 0x00045934
		private OperateResult SendPre(byte[] send)
		{
			ILogNet logNet = base.LogNet;
			if (logNet != null)
			{
				logNet.WriteDebug("Send " + send.ToHexString(' '));
			}
			return base.Send(this.CoreSocket, send);
		}

		/// <summary>
		/// 设置读取震动传感器的状态数据<br />
		/// Set to read the status data of the shock sensor
		/// </summary>
		/// <returns>是否发送成功</returns>
		// Token: 0x06000C07 RID: 3079 RVA: 0x00047777 File Offset: 0x00045977
		[HslMqttApi]
		public OperateResult SetReadStatus()
		{
			return this.SendPre(VibrationSensorClient.BulidLongMessage(this.address, 1, null));
		}

		/// <summary>
		/// 设置读取震动传感器的实时加速度<br />
		/// Set the real-time acceleration of the vibration sensor
		/// </summary>
		/// <returns>是否发送成功</returns>
		// Token: 0x06000C08 RID: 3080 RVA: 0x0004778C File Offset: 0x0004598C
		[HslMqttApi]
		public OperateResult SetReadActual()
		{
			return this.SendPre(VibrationSensorClient.BulidLongMessage(this.address, 2, null));
		}

		/// <summary>
		/// 设置当前的震动传感器的数据发送间隔为指定的时间，单位为秒<br />
		/// Set the current vibration sensor data transmission interval to the specified time in seconds
		/// </summary>
		/// <param name="seconds">时间信息，单位为秒</param>
		/// <returns>是否发送成功</returns>
		// Token: 0x06000C09 RID: 3081 RVA: 0x000477A4 File Offset: 0x000459A4
		[HslMqttApi]
		public OperateResult SetReadStatusInterval(int seconds)
		{
			byte[] array = new byte[6];
			array[0] = BitConverter.GetBytes(this.address)[0];
			array[1] = BitConverter.GetBytes(this.address)[1];
			BitConverter.GetBytes(seconds).CopyTo(array, 2);
			return this.SendPre(VibrationSensorClient.BulidLongMessage(this.address, 16, array));
		}

		/// <summary>
		/// 接收到震动传感器峰值数据时触发<br />
		/// Triggered when peak data of vibration sensor is received
		///             </summary>
		// Token: 0x1400000E RID: 14
		// (add) Token: 0x06000C0A RID: 3082 RVA: 0x00047800 File Offset: 0x00045A00
		// (remove) Token: 0x06000C0B RID: 3083 RVA: 0x00047838 File Offset: 0x00045A38
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public event VibrationSensorClient.OnPeekValueReceiveDelegate OnPeekValueReceive;

		/// <summary>
		/// 接收到震动传感器实时数据时触发<br />
		/// Triggered when real-time data from shock sensor is received
		///             </summary>
		// Token: 0x1400000F RID: 15
		// (add) Token: 0x06000C0C RID: 3084 RVA: 0x00047870 File Offset: 0x00045A70
		// (remove) Token: 0x06000C0D RID: 3085 RVA: 0x000478A8 File Offset: 0x00045AA8
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public event VibrationSensorClient.OnActualValueReceiveDelegate OnActualValueReceive;

		/// <summary>
		/// 当客户端连接成功触发事件，就算是重新连接服务器后，也是会触发的<br />
		/// The event is triggered when the client is connected successfully, even after reconnecting to the server.
		/// </summary>
		// Token: 0x14000010 RID: 16
		// (add) Token: 0x06000C0E RID: 3086 RVA: 0x000478E0 File Offset: 0x00045AE0
		// (remove) Token: 0x06000C0F RID: 3087 RVA: 0x00047918 File Offset: 0x00045B18
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public event VibrationSensorClient.OnClientConnectedDelegate OnClientConnected;

		/// <summary>
		/// 当网络发生异常的时候触发的事件，用户应该在事件里进行重连服务器
		/// </summary>
		// Token: 0x14000011 RID: 17
		// (add) Token: 0x06000C10 RID: 3088 RVA: 0x00047950 File Offset: 0x00045B50
		// (remove) Token: 0x06000C11 RID: 3089 RVA: 0x00047988 File Offset: 0x00045B88
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public event EventHandler OnNetworkError;

		/// <summary>
		/// 获取或设置当前客户端的连接超时时间，默认10,000毫秒，单位ms<br />
		/// Gets or sets the connection timeout of the current client. The default is 10,000 milliseconds. The unit is ms.
		/// </summary>
		// Token: 0x170001D0 RID: 464
		// (get) Token: 0x06000C12 RID: 3090 RVA: 0x000479BD File Offset: 0x00045BBD
		// (set) Token: 0x06000C13 RID: 3091 RVA: 0x000479C5 File Offset: 0x00045BC5
		public int ConnectTimeOut
		{
			get
			{
				return this.connectTimeOut;
			}
			set
			{
				this.connectTimeOut = value;
			}
		}

		/// <summary>
		/// 获取或设置当前的客户端假死超时检查时间，单位为秒，默认60秒，60秒内没有接收到传感器的数据，则强制重连。
		/// </summary>
		// Token: 0x170001D1 RID: 465
		// (get) Token: 0x06000C14 RID: 3092 RVA: 0x000479CE File Offset: 0x00045BCE
		// (set) Token: 0x06000C15 RID: 3093 RVA: 0x000479D6 File Offset: 0x00045BD6
		public int CheckSeconds
		{
			get
			{
				return this.checkSeconds;
			}
			set
			{
				this.checkSeconds = value;
			}
		}

		/// <summary>
		/// 当前设备的地址信息
		/// </summary>
		// Token: 0x170001D2 RID: 466
		// (get) Token: 0x06000C16 RID: 3094 RVA: 0x000479DF File Offset: 0x00045BDF
		// (set) Token: 0x06000C17 RID: 3095 RVA: 0x000479E7 File Offset: 0x00045BE7
		public ushort Address
		{
			get
			{
				return this.address;
			}
			set
			{
				this.address = value;
			}
		}

		/// <inheritdoc />
		// Token: 0x06000C18 RID: 3096 RVA: 0x000479F0 File Offset: 0x00045BF0
		public override string ToString()
		{
			return string.Format("VibrationSensorClient[{0}:{1}]", this.ipAddress, this.port);
		}

		/// <summary>
		/// 根据地址，命令，数据，创建向传感器发送的数据信息
		/// </summary>
		/// <param name="address">设备地址</param>
		/// <param name="cmd">命令</param>
		/// <param name="data">数据信息</param>
		/// <returns>原始的数据内容</returns>
		// Token: 0x06000C19 RID: 3097 RVA: 0x00047A10 File Offset: 0x00045C10
		public static byte[] BulidLongMessage(ushort address, byte cmd, byte[] data)
		{
			bool flag = data == null;
			if (flag)
			{
				data = new byte[0];
			}
			byte[] array = new byte[16 + data.Length];
			array[0] = 170;
			array[1] = 85;
			array[2] = 127;
			array[3] = BitConverter.GetBytes(address)[1];
			array[4] = BitConverter.GetBytes(address)[0];
			array[5] = cmd;
			array[6] = 1;
			array[7] = 0;
			array[8] = 1;
			array[9] = 1;
			array[10] = BitConverter.GetBytes(data.Length)[1];
			array[11] = BitConverter.GetBytes(data.Length)[0];
			data.CopyTo(array, 12);
			int num = (int)array[3];
			for (int i = 4; i < array.Length - 4; i++)
			{
				num ^= (int)array[i];
			}
			array[array.Length - 4] = (byte)num;
			array[array.Length - 3] = 127;
			array[array.Length - 2] = 170;
			array[array.Length - 1] = 237;
			return array;
		}

		/// <summary>
		/// 检查当前的数据是否XOR校验成功
		/// </summary>
		/// <param name="data">数据信息</param>
		/// <returns>校验结果</returns>
		// Token: 0x06000C1A RID: 3098 RVA: 0x00047AF0 File Offset: 0x00045CF0
		public static bool CheckXor(byte[] data)
		{
			int num = (int)data[3];
			for (int i = 4; i < data.Length - 4; i++)
			{
				num ^= (int)data[i];
			}
			return BitConverter.GetBytes(num)[0] == data[data.Length - 4];
		}

		// Token: 0x04000343 RID: 835
		private int isReConnectServer = 0;

		// Token: 0x04000344 RID: 836
		private bool closed = false;

		// Token: 0x04000345 RID: 837
		private string ipAddress = string.Empty;

		// Token: 0x04000346 RID: 838
		private int port = 1883;

		// Token: 0x04000347 RID: 839
		private int connectTimeOut = 10000;

		// Token: 0x04000348 RID: 840
		private Timer timerCheck;

		// Token: 0x04000349 RID: 841
		private DateTime activeTime = DateTime.Now;

		// Token: 0x0400034A RID: 842
		private int checkSeconds = 60;

		// Token: 0x0400034B RID: 843
		private int CheckTimeoutCount = 0;

		// Token: 0x0400034C RID: 844
		private ushort address = 1;

		// Token: 0x0400034D RID: 845
		private IByteTransform byteTransform;

		/// <summary>
		/// 震动传感器峰值数据事件委托<br />
		/// Shock sensor peak data event delegation
		/// </summary>
		/// <param name="peekValue">峰值信息</param>
		// Token: 0x020003C1 RID: 961
		// (Invoke) Token: 0x060027E6 RID: 10214
		public delegate void OnPeekValueReceiveDelegate(VibrationSensorPeekValue peekValue);

		/// <summary>
		/// 震动传感器实时数据事件委托<br />
		/// Vibration sensor real-time data event delegation
		/// </summary>
		/// <param name="actualValue">实际信息</param>
		// Token: 0x020003C2 RID: 962
		// (Invoke) Token: 0x060027EA RID: 10218
		public delegate void OnActualValueReceiveDelegate(VibrationSensorActualValue actualValue);

		/// <summary>
		/// 连接服务器成功的委托<br />
		/// Connection server successfully delegated
		/// </summary>
		// Token: 0x020003C3 RID: 963
		// (Invoke) Token: 0x060027EE RID: 10222
		public delegate void OnClientConnectedDelegate();
	}
}
